﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Diagnostics;

namespace net.veekee.common.data
{
    public class XMLReader : AFile
    {
        private int level = 0;
        private XmlTextReader reader = null;
        private System.IO.StreamReader stream = null;

        public override bool IsValid
        {
            get
            {
                return (this.reader != null);
            }
        }

        public XMLReader(String filename)
            : base(filename)
        {
            if (!System.IO.File.Exists(this.fileName))
                return;
            this.stream = new System.IO.StreamReader(filename);
            this.reader = new XmlTextReader(this.stream);
            reader.Read();
        }

        private XMLItem GetNextItem(String separatorName)
        {
            XMLItem current = new XMLItem();
            current.Name = this.reader.Name;
            current.Completed = false;

            // Trace.WriteLine(new String('\t', this.level) + current.Name);
            try
            {
                while (this.reader.MoveToNextAttribute())
                    current.AddProperty(reader.Name, reader.Value);
            }
            catch(Exception e)
            {
                Log.GetInstance().Error("Item {0} = Error while parsing properties: {1}", current.Name, e.ToString());
            }

            try
            {
                while (reader.Read())
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (this.reader.Name.Equals("") || this.reader.Name.Equals(separatorName) || this.reader.Name.Equals(current.Name))
                            {
                                current.Completed = true;
                                return current;
                            }
                            this.level++;
                            current.AddChild(this.GetNextItem(separatorName));
                            this.level--;
                            if (current.Completed)
                                return current;
                            break;
                        case XmlNodeType.Text:
                            current.Value = this.reader.Value;
                            break;
                        case XmlNodeType.EndElement:
                            if (this.reader.Name.Equals(current.Name))
                            {
                                current.Completed = true;
                                return current;
                            }
                            break;
                    }
                }
            }
            catch (Exception e)
            {
                Log.GetInstance().Error("Line {0} ; Item {1} = Error while parsing datas: {2}", this.reader.LineNumber, current.Name, e.ToString());
                switch (reader.NodeType)
                {
                    case XmlNodeType.Text:
                        current.Value = this.reader.Value;
                        break;
                }
                reader.ResetState();
            }
            current.Completed = true;
            return current;
        }

        public XMLItem Next(String elt)
        {
            XMLItem root = new XMLItem();

            bool letsContinue = false;

            do
            {
                try
                {
                    switch (reader.NodeType)
                    {
                        case XmlNodeType.Element:
                            if (reader.Name.Equals(elt))
                            {
                                return this.GetNextItem(elt);
                            }
                            break;
                    }
                    letsContinue = reader.Read();
                }
                catch (Exception e)
                {
                    Log.GetInstance().Error("Line {0} ; Error while parsing tags: {1}", this.reader.LineNumber, e.ToString());
                    letsContinue = false;
                }
            } while (letsContinue);
            return null;
        }

        public override void Dispose()
        {
            if (this.reader != null)
                this.reader.Close();
            if (this.stream != null)
                this.stream.Close();
        }
    }
}
